/*
 *所有关于storagelocationmodel类的业务代码应在此处编写
*可使用repository.调用常用方法，获取EF/Dapper等信息
*如果需要事务请使用repository.DbContextBeginTransaction
*也可使用DBServerProvider.手动获取数据库相关信息
*用户信息、权限、角色等使用UserContext.Current操作
*storagelocationmodelService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter
*/
using VOL.Core.BaseProvider;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
using System.Linq;
using VOL.Core.Utilities;
using System.Linq.Expressions;
using VOL.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.demo.IRepositories;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace VOL.demo.Services
{
    public partial class storagelocationmodelService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IstoragelocationmodelRepository _repository;//访问数据库

        [ActivatorUtilitiesConstructor]
        public storagelocationmodelService(
            IstoragelocationmodelRepository dbRepository,
            IHttpContextAccessor httpContextAccessor
            )
        : base(dbRepository)
        {
            _httpContextAccessor = httpContextAccessor;
            _repository = dbRepository;
            //多租户会用到这init代码，其他情况可以不用
            //base.Init(dbRepository);
        }

        /// <summary>
        /// 添加库位
        /// </summary>
        /// <param name="storageLocation">库位信息</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> AddStorageLocationAsync(storagelocationmodel storageLocation)
        {
            var response = new WebResponseContent();
            
            try
            {
                // 参数验证
                if (storageLocation == null)
                {
                    return response.Error("库位信息不能为空");
                }

                if (string.IsNullOrEmpty(storageLocation.locationCode))
                {
                    return response.Error("库位编号不能为空");
                }

                if (string.IsNullOrEmpty(storageLocation.locationName))
                {
                    return response.Error("库位名称不能为空");
                }

                // 检查库位编号是否已存在
                if (await IsLocationCodeExistsAsync(storageLocation.locationCode))
                {
                    return response.Error("库位编号已存在");
                }

                // 设置创建信息
                storageLocation.CreateDate = DateTime.Now;
                storageLocation.IsDel = 0; // 0表示未删除
                storageLocation.Creator = "admin"; // 这里可以从用户上下文获取

                // 保存到数据库
                repository.Add(storageLocation);
                
                return response.OK("库位添加成功", storageLocation);
            }
            catch (Exception ex)
            {
                return response.Error($"添加库位失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 更新库位
        /// </summary>
        /// <param name="storageLocation">库位信息</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> UpdateStorageLocationAsync(storagelocationmodel storageLocation)
        {
            var response = new WebResponseContent();
            
            try
            {
                // 参数验证
                if (storageLocation == null)
                {
                    return response.Error("库位信息不能为空");
                }

                if (storageLocation.Id <= 0)
                {
                    return response.Error("库位ID不能为空");
                }

                if (string.IsNullOrEmpty(storageLocation.locationCode))
                {
                    return response.Error("库位编号不能为空");
                }

                if (string.IsNullOrEmpty(storageLocation.locationName))
                {
                    return response.Error("库位名称不能为空");
                }

                // 检查库位是否存在
                var existingLocation = await GetStorageLocationByIdAsync(storageLocation.Id);
                if (existingLocation == null)
                {
                    return response.Error("库位不存在");
                }

                // 检查库位编号是否已被其他记录使用
                if (await IsLocationCodeExistsAsync(storageLocation.locationCode, storageLocation.Id))
                {
                    return response.Error("库位编号已被其他记录使用");
                }

                // 更新字段
                existingLocation.locationCode = storageLocation.locationCode;
                existingLocation.locationName = storageLocation.locationName;
                existingLocation.locationCapacity = storageLocation.locationCapacity;
                existingLocation.UserId = storageLocation.UserId;
                existingLocation.locationState = storageLocation.locationState;
                existingLocation.locationDesc = storageLocation.locationDesc;
                existingLocation.locationSort = storageLocation.locationSort;
                existingLocation.warehouseId = storageLocation.warehouseId;
                existingLocation.ModifyDate = DateTime.Now;
                existingLocation.Modifier = "admin"; // 这里可以从用户上下文获取

                // 保存到数据库
                repository.Update(existingLocation);
                
                return response.OK("库位更新成功", existingLocation);
            }
            catch (Exception ex)
            {
                return response.Error($"更新库位失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 删除库位
        /// </summary>
        /// <param name="id">库位ID</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> DeleteStorageLocationAsync(int id)
        {
            var response = new WebResponseContent();
            
            try
            {
                if (id <= 0)
                {
                    return response.Error("库位ID不能为空");
                }

                // 检查库位是否存在
                var existingLocation = await GetStorageLocationByIdAsync(id);
                if (existingLocation == null)
                {
                    return response.Error("库位不存在");
                }

                // 软删除（设置删除标识）
                existingLocation.IsDel = 1; // 1表示已删除
                existingLocation.ModifyDate = DateTime.Now;
                existingLocation.Modifier = "admin"; // 这里可以从用户上下文获取

                repository.Update(existingLocation);
                
                return response.OK("库位删除成功");
            }
            catch (Exception ex)
            {
                return response.Error($"删除库位失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 批量删除库位
        /// </summary>
        /// <param name="ids">库位ID列表</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> BatchDeleteStorageLocationAsync(List<int> ids)
        {
            var response = new WebResponseContent();
            
            try
            {
                if (ids == null || ids.Count == 0)
                {
                    return response.Error("请选择要删除的库位");
                }

                int successCount = 0;
                int failCount = 0;

                foreach (var id in ids)
                {
                    var result = await DeleteStorageLocationAsync(id);
                    if (result.Status)
                    {
                        successCount++;
                    }
                    else
                    {
                        failCount++;
                    }
                }

                if (failCount == 0)
                {
                    return response.OK($"批量删除成功，共删除{successCount}条库位记录");
                }
                else
                {
                    return response.OK($"批量删除完成，成功{successCount}条，失败{failCount}条");
                }
            }
            catch (Exception ex)
            {
                return response.Error($"批量删除库位失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 根据ID获取库位信息
        /// </summary>
        /// <param name="id">库位ID</param>
        /// <returns>库位信息</returns>
        public async Task<storagelocationmodel> GetStorageLocationByIdAsync(int id)
        {
            try
            {
                // 修复：IsDel可能为null，需要兼容null和0的情况
                return repository.FindFirst(x => x.Id == id && (x.IsDel == 0 || x.IsDel == null));
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 检查库位编号是否已存在
        /// </summary>
        /// <param name="locationCode">库位编号</param>
        /// <param name="excludeId">排除的ID（用于编辑时检查）</param>
        /// <returns>是否存在</returns>
        public async Task<bool> IsLocationCodeExistsAsync(string locationCode, int? excludeId = null)
        {
            try
            {
                if (string.IsNullOrEmpty(locationCode))
                {
                    return false;
                }

                if (excludeId.HasValue)
                {
                    return repository.Find(x => x.locationCode == locationCode && (x.IsDel == 0 || x.IsDel == null) && x.Id != excludeId.Value).Any();
                }
                else
                {
                    return repository.Find(x => x.locationCode == locationCode && (x.IsDel == 0 || x.IsDel == null)).Any();
                }
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 获取库位分页列表
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">每页记录数</param>
        /// <param name="keyword">搜索关键词</param>
        /// <param name="warehouseId">仓库ID</param>
        /// <param name="locationState">库位状态</param>
        /// <returns>分页结果</returns>
        public async Task<(List<storagelocationmodel> Data, int TotalCount)> GetStorageLocationPagedAsync(
            int pageIndex = 1, 
            int pageSize = 20, 
            string keyword = null, 
            long? warehouseId = null, 
            string locationState = null)
        {
            try
            {
                // 修复：IsDel可能为null，需要兼容null和0的情况
                var query = repository.Find(x => x.IsDel == 0 || x.IsDel == null).AsQueryable();

                // 关键词搜索
                if (!string.IsNullOrEmpty(keyword))
                {
                    query = query.Where(x => 
                        x.locationCode.Contains(keyword) || 
                        x.locationName.Contains(keyword) ||
                        x.locationDesc.Contains(keyword));
                }

                // 仓库ID筛选
                if (warehouseId.HasValue)
                {
                    query = query.Where(x => x.warehouseId == warehouseId.Value);
                }

                // 库位状态筛选
                if (!string.IsNullOrEmpty(locationState))
                {
                    query = query.Where(x => x.locationState == locationState);
                }

                // 获取总数
                var totalCount = query.Count();

                // 分页查询数据并按创建时间倒序
                var data = query.OrderByDescending(x => x.CreateDate)
                    .Skip((pageIndex - 1) * pageSize)
                    .Take(pageSize)
                    .ToList();

                return (data, totalCount);
            }
            catch (Exception ex)
            {
                throw new Exception($"获取库位分页列表失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 批量修改库位
        /// </summary>
        /// <param name="dto">批量修改DTO</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> BatchUpdateStorageLocationAsync(BatchUpdateStorageLocationDto dto)
        {
            var response = new WebResponseContent();
            
            try
            {
                // 参数验证
                if (dto == null)
                {
                    return response.Error("批量修改参数不能为空");
                }

                if (dto.Ids == null || dto.Ids.Count == 0)
                {
                    return response.Error("请选择要修改的库位");
                }

                // 检查是否至少有一个字段需要修改
                bool hasUpdateField = !string.IsNullOrEmpty(dto.LocationState) ||
                                     dto.WarehouseId.HasValue ||
                                     dto.UserId.HasValue ||
                                     !string.IsNullOrEmpty(dto.LocationCapacity) ||
                                     !string.IsNullOrEmpty(dto.LocationDesc) ||
                                     !string.IsNullOrEmpty(dto.LocationSort);

                if (!hasUpdateField)
                {
                    return response.Error("请至少选择一个字段进行修改");
                }

                int successCount = 0;
                int failCount = 0;
                var errorMessages = new List<string>();
                var locationsToUpdate = new List<storagelocationmodel>();

                // 收集所有需要更新的库位
                foreach (var id in dto.Ids)
                {
                    try
                    {
                        // 获取库位信息
                        var location = await GetStorageLocationByIdAsync(id);
                        if (location == null)
                        {
                            errorMessages.Add($"ID为{id}的库位不存在");
                            failCount++;
                            continue;
                        }

                        // 根据传入的字段进行更新
                        if (!string.IsNullOrEmpty(dto.LocationState))
                        {
                            location.locationState = dto.LocationState;
                        }

                        if (dto.WarehouseId.HasValue)
                        {
                            location.warehouseId = dto.WarehouseId.Value;
                        }

                        if (dto.UserId.HasValue)
                        {
                            location.UserId = dto.UserId.Value;
                        }

                        if (!string.IsNullOrEmpty(dto.LocationCapacity))
                        {
                            location.locationCapacity = dto.LocationCapacity;
                        }

                        if (!string.IsNullOrEmpty(dto.LocationDesc))
                        {
                            location.locationDesc = dto.LocationDesc;
                        }

                        if (!string.IsNullOrEmpty(dto.LocationSort))
                        {
                            location.locationSort = dto.LocationSort;
                        }

                        // 更新修改信息
                        location.ModifyDate = DateTime.Now;
                        location.Modifier = "admin"; // 这里可以从用户上下文获取

                        // 添加到批量更新列表
                        locationsToUpdate.Add(location);
                        successCount++;
                    }
                    catch (Exception ex)
                    {
                        errorMessages.Add($"ID为{id}的库位修改失败：{ex.Message}");
                        failCount++;
                    }
                }

                // 批量保存到数据库（关键：saveChanges = true）
                if (locationsToUpdate.Count > 0)
                {
                    repository.UpdateRange(locationsToUpdate, saveChanges: true);
                }

                // 返回结果
                if (failCount == 0)
                {
                    return response.OK($"批量修改成功，共修改{successCount}条库位记录");
                }
                else if (successCount == 0)
                {
                    return response.Error($"批量修改失败：{string.Join("; ", errorMessages)}");
                }
                else
                {
                    return response.OK($"批量修改完成，成功{successCount}条，失败{failCount}条。失败原因：{string.Join("; ", errorMessages)}");
                }
            }
            catch (Exception ex)
            {
                return response.Error($"批量修改库位失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 批量修改库位的仓库ID
        /// </summary>
        /// <param name="dto">批量修改仓库DTO</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> BatchUpdateWarehouseIdAsync(BatchUpdateWarehouseDto dto)
        {
            var response = new WebResponseContent();
            
            try
            {
                // 参数验证
                if (dto == null)
                {
                    return response.Error("批量修改参数不能为空");
                }

                if (dto.Ids == null || dto.Ids.Count == 0)
                {
                    return response.Error("请选择要修改的库位");
                }

                if (dto.WarehouseId <= 0)
                {
                    return response.Error("仓库ID不能为空");
                }

                int successCount = 0;
                int failCount = 0;
                var errorMessages = new List<string>();
                var locationsToUpdate = new List<storagelocationmodel>();

                // 收集所有需要更新的库位
                foreach (var id in dto.Ids)
                {
                    try
                    {
                        // 获取库位信息
                        var location = await GetStorageLocationByIdAsync(id);
                        if (location == null)
                        {
                            errorMessages.Add($"ID为{id}的库位不存在");
                            failCount++;
                            continue;
                        }

                        // 只修改仓库ID
                        location.warehouseId = dto.WarehouseId;

                        // 更新修改信息
                        location.ModifyDate = DateTime.Now;
                        location.Modifier = "admin"; // 这里可以从用户上下文获取

                        // 添加到批量更新列表
                        locationsToUpdate.Add(location);
                        successCount++;
                    }
                    catch (Exception ex)
                    {
                        errorMessages.Add($"ID为{id}的库位修改失败：{ex.Message}");
                        failCount++;
                    }
                }

                // 批量保存到数据库
                if (locationsToUpdate.Count > 0)
                {
                    repository.UpdateRange(locationsToUpdate, saveChanges: true);
                }

                // 返回结果
                if (failCount == 0)
                {
                    return response.OK($"批量修改成功，共修改{successCount}条库位的仓库ID");
                }
                else if (successCount == 0)
                {
                    return response.Error($"批量修改失败：{string.Join("; ", errorMessages)}");
                }
                else
                {
                    return response.OK($"批量修改完成，成功{successCount}条，失败{failCount}条。失败原因：{string.Join("; ", errorMessages)}");
                }
            }
            catch (Exception ex)
            {
                return response.Error($"批量修改库位仓库ID失败：{ex.Message}");
            }
        }
  }
}
